package com.ferry.config.client.listener;

import com.ferry.config.client.annotation.FerryConfig;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;

public class AnnotationConfigChangeListener implements ConfigChangeListener {
    private static final Logger logger = LoggerFactory.getLogger(AnnotationConfigChangeListener.class);

    private Class config;

    public AnnotationConfigChangeListener(Class config) {
        this.config = config;
    }

    @Override
    public void changed(String key, String oldValue, String newValue) {
        Field[] fields = config.getDeclaredFields();
        for (Field field : fields) {
            try {
                if (field.isAnnotationPresent(FerryConfig.class)) {
                    FerryConfig configParam = field.getAnnotation(FerryConfig.class);
                    if (key.equals(configParam.key())) {
                        field.setAccessible(true);
                        field.set(config, transferValueType(field, newValue));
                    }
                }
            } catch (Exception e) {
                logger.error("AnnotationConfigChangeListener.changed Exception, key:{}, oldValue:{}, newValue:{}",
                                    key, oldValue, newValue, e);
            }
        }
    }

    private Object transferValueType(Field field, String value) {
        return transferValueTypePrimitively(field, value);
    }

    public static Object transferValueTypePrimitively(Field field, String value){
        Object result = null;
        String fieldName = field.getDeclaringClass().getName() + "." + field.getName();
        String typeName = field.getType().getSimpleName();
        try {
            if (StringUtils.equals(typeName, "String")) {
                result = value;
            } else if (StringUtils.equals(typeName, "int") || StringUtils.equals(typeName, "Integer")) {
                result = Integer.valueOf(value);
            } else if (StringUtils.equals(typeName, "long") || StringUtils.equals(typeName, "Long")) {
                result = Long.valueOf(value);
            } else if (StringUtils.equals(typeName, "float") || StringUtils.equals(typeName, "Float")) {
                result = Float.valueOf(value);
            } else if (StringUtils.equals(typeName, "double") || StringUtils.equals(typeName, "Double")) {
                result = Double.valueOf(value);
            } else if (StringUtils.equals(typeName, "boolean") || StringUtils.equals(typeName, "Boolean")) {
                result = Boolean.valueOf(value);
            } else {
                //ignore
            }
        } catch (Exception e) {
            logger.error("transferValueTypePrimitively Exception, field:{}, value:{}", field.toString(), value);
        }
        return result;
    }
}